<template>
  <section class="file-list">
    <el-tabs type="border-card">
      <el-tab-pane :style="{height:tableH+'px',overflow: 'scroll'}" label="文件列表">
          <el-radio-group style="display:flex" v-model="data.curFile" @change="fileChange">
            <el-radio v-for="item in data.files" :key="item.label" :label="item.label" />
          </el-radio-group>
        <!-- <div style="display:block" v-for="(item, index) in data.files" :key="item.Name">{{ item.label }}</div> -->
      </el-tab-pane>
    </el-tabs>
  </section>
  <section class="draw-container">
    <section class="draw-container-inner">
      <xr-node ref="xrnode" />
    </section>
  </section>
  <section class="node-list">
    <el-tabs type="border-card">
      <el-tab-pane label="算子组件">
        <el-input v-model="filterText" placeholder="过滤关键字" />
        <el-scrollbar :height="tableH">
        <el-tree ref="treeRef" :props="{ class: customNodeClass }" :data="data.tree" @node-expand="handleNodeExpand"
          :filter-node-method="filterTreeNode"></el-tree>
        </el-scrollbar>
      </el-tab-pane>
    </el-tabs>
  </section>
</template>
  
<script setup  lang="ts">
import { ref, reactive, watch, nextTick ,onMounted} from "vue";
import XrNode from '@/components/XrNode.vue';
import { easyapi } from '@/lib/lib.ts';
// import { ElTree as ElTreeType } from "element-plus/lib/components/tree/index.js";

//树目录接口
interface Tree {
  [key: string]: any
}
interface Data {
  [property: string]: any
  // tree:any
  // nodes:any
  // files:any
  // curFile:string
}
const filterText = ref('') //过滤条件
const treeRef = ref() //导航组件
const xrnode: any = ref(null);//画布组件
const tableH = ref(0);
const data: Data = reactive({
  tree: [],//树导航
  nodes: [],//节点列表
  files: [],//文件列表
  curFile: "",//当前选择的文件
})

//监视节点变化
watch(filterText, (val) => {
  treeRef.value!.filter(val)
})
onMounted(()=>{
      getWindowResize()
      window.addEventListener('resize', getWindowResize)
    })
    const getWindowResize = () => {
      tableH.value = window.innerHeight*0.9
    }
//过滤节点
const filterTreeNode = (value: string, _data: Tree, node: { data: { label: string | string[]; }; }) => {
  if (!value) return true
  nextTick(() => {
    //获取所有允许拖拽的DOM节点
    const doms = document.querySelectorAll(".allow-drag-node")
    doms.forEach(dom => {
      const existDom = eventDoms.find(item => item === dom)
      if (!existDom) {
        //为DOM节点添加鼠标按下事件
        dom.addEventListener("mousedown", mouseMoveDown)
        eventDoms.push(dom)
      }
    })
  })
  return node.data.label.includes(value)
}

//设置组态节点(加载节点数据)
const loadNodes = () => {
  easyapi("/v1/api/nodes", "get", null, (rsp: { data: any; }) => {
    data.nodes = rsp.data;
    console.log(rsp)
    let t: any = {}
    data.nodes.forEach((node: any, index: any) => {
      let model = t[node.data.model];
      if (model == null) {
        model = [];
        t[node.data.model] = model;
      }
      model.push({ id: index, label: node.label + "[" + node.data.name + "]" })
    })
    let t1 = Object.entries(t);
    data.tree = [];
    t1.forEach((item: any) => {
      item[1].sort((a, b) => {
        if (a.label < b.label) {
          return -1;
        } else if (a.label > b.label) {
          return 1;
        } else {
          return 0;
        }
      });
      data.tree.push({ label: item[0], children: item[1] });
      data.tree.sort((a, b) => {
        if (a.label < b.label) {
          return -1;
        } else if (a.label > b.label) {
          return 1;
        } else {
          return 0;
        }
      })
    })
  })
}


//加载文件列表
easyapi("/v1/api/list", "get", null, (rsp: { data: any; }) => {
  data.files = rsp.data;
  loadNodes();
})

//切换文件
const fileChange = (name: string) => {
  //加载文件列表
  if (name == "") {
    return;
  }

  easyapi("/v1/api/file?path=" + name, "get", null, (rsp: { data: { data: string; }; }) => {
    let obj = JSON.parse(rsp.data.data);
    xrnode.value.loadGraph(obj);
  })
}

//已绑定事件的DOM集合
const eventDoms: any[] = []

/**
 * 自定义树节点样式
 */
const customNodeClass = (_data: any, node: any) => {
  if (node.isLeaf) {
    return 'allow-drag-node'
  }
  return null
}

/** 
 * 树节点展开事件
 */
const handleNodeExpand = () => {
  nextTick(() => {
    //获取所有允许拖拽的DOM节点
    const doms = document.querySelectorAll(".allow-drag-node")
    doms.forEach(dom => {
      const existDom = eventDoms.find(item => item === dom)
      if (!existDom) {
        //为DOM节点添加鼠标按下事件
        dom.addEventListener("mousedown", mouseMoveDown)
        eventDoms.push(dom)
      }
    })
  })
}

//克隆DOM对象
let cloneDom: any = null
//选中的树节点数据
let selectedTreeNodeData: any = null
/**
 * 鼠标按下事件
 */
const mouseMoveDown = (event: any) => {
  //获取树节点数据
  const treeNodeDataId = treeRef.value.getNode(event.currentTarget.dataset.key).data.id
  selectedTreeNodeData = data.nodes[treeNodeDataId]
  //克隆DOM节点，并设置位置信息
  const currentDom = event.currentTarget
  cloneDom = currentDom.cloneNode(true)
  cloneDom.style.position = "absolute"
  cloneDom.style.left = `${event.x - 20}px`
  cloneDom.style.top = `${event.y + 1}px`
  cloneDom.style.opacity = '0.8'
  cloneDom.style.zIndex = '999'
  //将克隆的DOM节点加入文档中
  document.body.appendChild(cloneDom)
  //添加对应的鼠标事件
  window.addEventListener("mousemove", mouseMoveEvent)
  window.addEventListener("mouseup", mouseUpEvent)
}

/**
 * 鼠标移动事件
 */
const mouseMoveEvent = (event: any) => {
  //设置克隆DOM的位置信息
  cloneDom.style.position = "absolute"
  cloneDom.style.left = `${event.x - 20}px`
  cloneDom.style.top = `${event.y + 1}px`
  cloneDom.style.opacity = '0.8'
  cloneDom.style.zIndex = '999'
}

/**
 * 鼠标抬起事件
 */
const mouseUpEvent = (event) => {
  //根据鼠标位置获取绘图容器DOM对象
  const graphDom = document.elementFromPoint(event.x, event.y)
  //如果鼠标位置为绘图容器，则进行后续处理
  const graphContainer: any = graphDom.parentNode
  if (graphContainer && graphContainer.id === "graph-container") {
    //获取绘图容器位置信息
    const { left: graphX, top: graphY } = graphDom.getBoundingClientRect()
    //获取鼠标相对于绘图容器的位置信息
    const drawX = event.x - graphX
    const drawY = event.y - graphY
    //在当前鼠标位置添加节点
    xrnode.value.addNode(drawX, drawY, selectedTreeNodeData)
  }
  //清空鼠标拖拽过程中的相关内容
  window.removeEventListener("mouseup", mouseUpEvent)
  window.removeEventListener("mousemove", mouseMoveEvent)
  cloneDom && document.body.removeChild(cloneDom)
  cloneDom = null
  selectedTreeNodeData = null
}

</script>

  
<style scoped>
/**
 * 整体布局
 */
/* .file-list,
.node-list,
.draw-container {
  float: left;
  height: 100%;
} */

.file-list{
  position: fixed;
    left: 0;
    width: 185px;
}
.node-list {
  width: 10%;
  position: fixed;
    right: 0;
}

/* .file-list {
  margin-left: -100%;
  border-right: 1px solid black;
  box-sizing: border-box;
} */

.draw-container {
  width: 79.5%;
}

/* .node-list {
  margin-left: -200px;
  border-left: 1px solid black;
  box-sizing: border-box;
} */

.draw-container-inner {
  /* margin-left: 200px;
  margin-right: 200px; */
  width: 79.7%;
  height: 95%;
  /* display: flex;
  flex-direction: column; */
  margin: 40px auto;
    /* display: flex; */
    position: fixed;
    left: 190px;
}

:deep(.allow-drag-node) {
  user-select: none
}


#stencil {
  width: 200px;
  height: 100%;
  position: relative;
  border-right: 1px solid #dfe3e8;
}

.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}

.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}

.logo.vue:hover {
  filter: drop-shadow(0 0 2em #42b883aa);
}

#stencil {
  width: 200px;
  height: 100%;
  position: relative;
  border-right: 1px solid #dfe3e8;
}

.btn_setting {
  margin: 2px 0px 2px 2px;
  width: 100px;
}

#graph-container {
  margin-top: 0px;
  width: calc(100% - 180px);
  height: 100%;
}

.x6-widget-stencil {
  background-color: #fff;
}

.x6-widget-stencil-title {
  background-color: #fff;
}

.x6-widget-stencil-group-title {
  background-color: #fff !important;
}

.x6-widget-transform {
  margin: -1px 0 0 -1px;
  padding: 0px;
  border: 1px solid #239edd;
}

.x6-widget-transform>div {
  border: 1px solid #239edd;
}

.x6-widget-transform>div:hover {
  background-color: #3dafe4;
}

.x6-widget-transform-active-handle {
  background-color: #3dafe4;
}

.x6-widget-transform-resize {
  border-radius: 0;
}

.x6-widget-selection-inner {
  border: 1px solid #239edd;
}

.x6-widget-selection-box {
  opacity: 0;
}
</style>
